Cleaner Group- and Messagelines for gnus in emacs

The gnus group and summary buffers by default looks pretty cluttered. I strongly recommend configuring gnus to make these buffers more readable. Here is a good base line configuration that removes some of the unnecessary information you likely don't care about as well as the [] / <> symbols. It also right-aligns the name of the sender and indents only the summary for threads. Don't forget to read the description of both of these custom variables to understand what this does and how!

(custom-set-variables
 (gnus-group-line-format "%M%S %3y %10s %G\n")
 (gnus-summary-line-format "%U%R %25.25a%ul%I  %S\n"))

That is already quite a lot better. But we can do better! If you, like me, get a lot of automated mail from various websites and lists. These often add some identifier string in front of the summary. These are often redundant with the sender name, so let's remove them. Gnus allows you to configure a regexp to remove anything you want from the start of the summary.

(custom-set-variables
 (gnus-list-identifiers
  (rx (or "[Stud.IP - Georg-August-Universität Göttingen]"
                                "[UNI-ALL]"
                                "[UNI-Studierende]"
                                "[FlexNow]"
                                "[AStA-News]"))))

But sometimes you do want to know what list a message is from, but the list name is not in the summary nor the sender. Gnus supports calling user written elisp functions from the format string. If you add the %u specifier, followed by a letter, gnus will call gnus-user-format-function-<letter> with the message header as argument. Let's use this to add the names of sourcehut mailing lists.

(defun gnus-user-format-function-l (header)
  "Returns name of sourcehut mailing list, if any"
  (let* ((extra (mail-header-extra header))
         (extract (lambda (key)
                    (if-let* ((content (alist-get key extra)))
                        (pcase (type-of content)
                          ('string
                           `(,content))
                          ('cons
                           (if (catch 'not-string
                                 (dolist (elem elems)
                                   (unless (eq 'string (typeof elem))
                                     (throw 'not-string t))))
                               '()
                             content))
                          (_
                           '())))))
         (all (append (funcall extract 'To)
                      (funcall extract 'Cc))))
    (catch 'break
      (dolist (address all)
        (when (string-match-p (regexp-quote "@lists.sr.ht")
                              address)
          (throw 'break
                 (format "  [%s]"
                         (string-remove-suffix
                          "@lists.sr.ht"
                          (car (mail-header-parse-address address)))))))
      "")))

To actually call this function, add %ul into the format string at an appropriate position.